package org.easy.module.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.easy.common.constant.RedisConstant;
import org.easy.common.constant.TipConstant;
import org.easy.common.domain.SysUserDO;
import org.easy.common.util.EncryptUtil;
import org.easy.common.util.MailUtil;
import org.easy.common.util.RedisUtil;
import org.easy.module.mapper.SysUserMapper;
import org.easy.module.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName: SysUserServiceImpl
 * @Description: 用户Service实现类
 * @Author zhouzhixin
 * @Date 2021/9/26
 * @Version 1.0
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserDO> implements SysUserService {

    SysUserMapper sysUserMapper;

    @Autowired
    public void init(SysUserMapper sysUserMapper) {
        this.sysUserMapper = sysUserMapper;
    }

    /**
     * <p>注册用户</p>
     *
     * @param sysUserDO
     * @return java.lang.Integer
     * @author zhouzhixin
     * @date 2021/9/26 14:54
     */
    @Override
    public String register(SysUserDO sysUserDO) {
        String flag = null;
        try {
            // 密码加密
            String uuid = UUID.randomUUID().toString();
            String password = EncryptUtil.encrypt(sysUserDO.getPassword(), uuid, "SHA-256", 1000);
            sysUserDO.setPassword(password);
            sysUserDO.setSalt(uuid);
            // 注册时先设置用户为不可用状态，邮箱激活后解除
            sysUserDO.setDeleted("1");
            // 新增用户数据
            if (sysUserMapper.insert(sysUserDO) > 0) {
                flag = TipConstant.REGISTER_SUCCESS;
                // 邮箱验证开始
                CompletableFuture<SysUserDO> async = CompletableFuture.supplyAsync(() -> {
                    sendActivationEmail(sysUserDO);
                    return sysUserDO;
                });
                async.whenCompleteAsync((sysUserDO1, throwable) -> log.info("id为：{}，的邮件发送完毕", sysUserDO1.getId()));
                // 由于发送邮件需要几秒的时间，故添加一秒的时差返回信息（假装处理复杂）
                TimeUnit.SECONDS.sleep(1);
            } else {
                flag = TipConstant.REGISTER_FAIL;
            }
        } catch (InterruptedException e) {
            log.error("注册用户过程出现异常", e);
            Thread.currentThread().interrupt();
        }
        return flag;
    }

    /**
     * <p>验证用户信息</p>
     *
     * @param sysUserDO
     * @return java.lang.String
     * @author zhouzhixin
     * @date 2021/9/29 10:43
     */
    @Override
    public String checkUserInfo(SysUserDO sysUserDO) {
        List<SysUserDO> userDOList;

        userDOList = sysUserMapper.selectList(new QueryWrapper<SysUserDO>().lambda()
                .eq(SysUserDO::getUsername, sysUserDO.getUsername()));
        if (!CollectionUtils.isEmpty(userDOList)) {
            return TipConstant.CHECK_USER_INFO_USERNAME_REPEAT;
        } else {
            userDOList = sysUserMapper.selectList(new QueryWrapper<SysUserDO>().lambda()
                    .eq(SysUserDO::getEmail, sysUserDO.getEmail()));
            if (!CollectionUtils.isEmpty(userDOList)) {
                return TipConstant.CHECK_USER_INFO_EMAIL_REPEAT;
            }
        }
        // 验证通过返回null，前端则不展示信息
        return null;
    }

    /**
     * <p>激活用户</p>
     *
     * @param sysUserDO
     * @return java.lang.String
     * @author zhouzhixin
     * @date 2021/9/30 15:07
     */
    @Override
    public String activation(SysUserDO sysUserDO, String checkCode) throws InterruptedException {
        String code = RedisUtil.StringOps.get(sysUserDO.getId() + RedisConstant.REGISTER_VALIDATION_CODE_CACHE_SUFFIX);
        if (StringUtils.isNotBlank(code) && checkCode.equals(code)) {
            sysUserDO.setDeleted("0");
            int flag = sysUserMapper.updateById(sysUserDO);
            if (flag > 0) {
                return TipConstant.ACTIVATION_SUCCESS;
            } else {
                return TipConstant.ACTIVATION_FAIL;
            }
        } else if (StringUtils.isBlank(code)) {
            // 验证邮件异步发送---start
            CompletableFuture<SysUserDO> async = CompletableFuture.supplyAsync(() -> {
                sendActivationEmail(sysUserDO);
                return sysUserDO;
            });
            async.whenCompleteAsync((sysUserDO1, throwable) -> log.info("id为：{}，的邮件发送完毕", sysUserDO1.getId()));
            // 由于发送邮件需要几秒的时间，故添加一秒的时差返回信息（假装处理复杂）
            TimeUnit.SECONDS.sleep(1);
            return TipConstant.ACTIVATION_CODE_EXPIRE;
        } else if (!checkCode.equals(code)) {
            return TipConstant.ACTIVATION_CODE_INVALID;
        }
        return TipConstant.ACTIVATION_UNKNOW_ERROR;
    }

    /**
     * <p>发送激活邮件</p>
     *
     * @param sysUserDO
     * @return void
     * @author zhouzhixin
     * @date 2021/9/30 15:16
     */
    @Override
    public void sendActivationEmail(SysUserDO sysUserDO) {
        int random = RandomUtils.nextInt(100000, 99999999);
        String subject = "EasyOA账户激活码";
        String content = "欢迎注册EasyOA系统后台账户\n" +
                "您创建的账户" + sysUserDO.getUsername() + "的激活码为：" + random +
                "，请在五分钟有效期内登录系统使用\n" +
                "在此之前，您的账户无法进行其它操作，感谢您的配合";
        MailUtil.sendMail(sysUserDO.getEmail(), subject, content);
        // redis存储五分钟随机验证码
        RedisUtil.StringOps.setIfAbsent(sysUserDO.getId() + RedisConstant.REGISTER_VALIDATION_CODE_CACHE_SUFFIX
                , String.valueOf(random), 5L, TimeUnit.MINUTES);
    }
}
